﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;

using Uniriotec.DC.RTSP;

namespace Uniriotec.DC
{
    public partial class ServerForm : Form
    {
        Server server = new Server();

        public ServerForm()
        {
            InitializeComponent();

            server.ConnectionStateChanged += ServerStatusChanged;
        }


        private void Server_FormClosed(object sender, FormClosedEventArgs e)
        {
            server.ForceStop();
        }

        private void ServerStatusChanged(object sender, EventArgs e)
        {
            serverStatusLabel.Text = GetStatusString(server.RtspConnectionState);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            server.EndConnection();
            this.Close();
            Dispose();
        }

        private void startServerButton_Click(object sender, EventArgs e)
        {
            server.ServerPort = 554;
            server.BaseVideoPath = @"C:\";

            server.InitializeServer();

            ThreadPool.QueueUserWorkItem(HandleServerLogic);
        }

        private string GetStatusString(RtspStates state)
        {
            string status = String.Empty;

            switch (state)
            {
                case RtspStates.STOPED: status = "Stoped"; break;
                case RtspStates.DISCONNECTED: status = "Disconnected (Accepting Requests)"; break;
                case RtspStates.INIT: status = "Connected"; break;
                case RtspStates.PLAYING: status = "Playing"; break;
                case RtspStates.READY: status = "Ready"; break;
            }
            return status;
        }

        /// <summary>
        /// Only for ThreadPool use
        /// </summary>
        /// <param name="state"></param>
        private void HandleServerLogic(object state)
        {
            HandleServerLogic();
        }

        private void HandleServerLogic()
        {
            server.RtspConnectionState = RtspStates.DISCONNECTED;

            server.WaitForConnection();

            //Initiate RTSPstate
            server.RtspConnectionState = RtspStates.INIT;

            //Wait for the SETUP message from the client
            RTSPAction request_type;
            bool setuped = false;

            while (!setuped)
            {
                request_type = server.parse_RTSP_request(); //blocking

                if (request_type == RTSPAction.SETUP)
                {
                    setuped = true;

                    //update RTSP state
                    server.RtspConnectionState = RtspStates.READY;

                    server.PrepareToSendVideo(server.VideoFileName);

                    //Send response
                    server.send_RTSP_response(200);
                }
            }

            //loop to handle RTSP requests
            while (server.ClientConnected)
            {
                //parse the request
                request_type = server.parse_RTSP_request(); //blocking

                if ((request_type == RTSPAction.PLAY) && (server.RtspConnectionState == RtspStates.READY))
                {
                    //send back response
                    server.send_RTSP_response(200);

                    server.StartSendingVideo();

                    //update state
                    server.RtspConnectionState = RtspStates.PLAYING;
                }
                else if ((request_type == RTSPAction.PAUSE) && (server.RtspConnectionState == RtspStates.PLAYING))
                {
                    //send back response
                    server.send_RTSP_response(200);

                    server.PauseSendingVideo();

                    //update state
                    server.RtspConnectionState = RtspStates.READY;
                }
                else if (request_type == RTSPAction.TEARDOWN)
                {
                    //send back response
                    server.send_RTSP_response(200);

                    server.EndConnection();

                    server.RtspConnectionState = RtspStates.STOPED;
                }
            }
        }

    }
}


